// ==============================================================================
// GenericMessageGateway provides generic functionality required by messaging 
// gateways.
// 
// GenericMessageGateway.cs
// @author Abel Perez <java.aperez@gmail.com>
// ==============================================================================


#region Imports

using System;
using System.Messaging;
using System.Xml;

#endregion

namespace Justa.Messaging
{
    /// <summary>
    /// GenericMessageGateway provides generic functionality required by
    /// messaging gateways.
    /// </summary>
    /// 
    public class GenericMessageGateway
    {
        /// <summary>
        /// The name that identifies this gateway.
        /// </summary>
        private string name;

        /// <summary>
        /// The default name given to this gateway when no name is specified.
        /// </summary>
        protected static string DEFAULT_NAME = "DefaultMessageReceiverGateway";

        /// <summary>
        /// 
        /// </summary>
        private string soapUrn = "http://schemas.xmlsoap.org/soap/envelope/";


        /// <summary>
        /// Simple Constructor.
        /// </summary>
        /// 
        public GenericMessageGateway()
        {
        }

        #region GenericMessageGateway Members

        /// <summary>
        /// Gets an MSMQ message queue based on the given destination name.
        /// When the specified destination does not exist in MSMQ the queue
        /// is automatically created.
        /// </summary>
        /// 
        /// <param name="destination">The destination queue to get from MSMQ.</param>
        /// <returns>MSMQ MessageQueue based on the given destination.</returns>
        /// 
        protected MessageQueue GetMessageQueue(string destination)
        {
            if (destination.IndexOf('\\') == -1)
            {
                destination = ".\\private$\\" + destination;
            }

            if (!MessageQueue.Exists(destination))
            {
                try
                {
                    MessageQueue.Create(destination);
                }
                catch (MessageQueueException exception)
                {
                    if ((int)exception.MessageQueueErrorCode != -1072824315)
                    {
                        throw new ApplicationException("Could not create message queue");
                    }
                }
            }
            return new MessageQueue(destination);
        }

        /// <summary>
        /// 
        /// </summary>
        /// 
        /// <param name="destination"></param>
        /// 
        /// <returns></returns>
        /// 
        protected string GetFullyQualifiedQueueName(string destination)
        {
            return "private$\\" + destination;
        }
        
        /// <summary>
        /// Constructs an Soap message that encapsulates the given message fragment 
        /// in the body of the new Soap message.
        /// </summary>
        /// 
        /// <param name="messageParentNode">The parent node of the given message fragment.</param>
        /// <param name="datasetId">The dataset id that will identify the given message fragment.</param>
        /// 
        protected virtual string ConstructSoapMessage(XmlElement messageParentNode, string datasetId)
        {
            return "<soap:Envelope xmlns:soap='" + this.SoapUrn + "'><soap:Header/><soap:Body><dataset id='" + datasetId + "'>" + messageParentNode.InnerXml + "</dataset></soap:Body></soap:Envelope>";
        }

        /// <summary>
        /// Gets the contents of the Message received by this gateway.
        /// </summary>
        /// 
        /// <param name="message">The Message recieved by this gateway.</param>
        /// 
        protected virtual string MessageRecieved(Message message)
        {
            return new System.IO.StreamReader(message.BodyStream).ReadToEnd();
        }

        /// <summary>
        /// Get's and Set's the name of this gateway.
        /// </summary>
        public string Name
        {
            get { return this.name; }
            set { this.name = value; }
        }

        /// <summary>
        /// Get's and Set's the default soap URN for soap messages.
        /// </summary>
        public string SoapUrn
        {
            get { return this.soapUrn; }
            set { this.soapUrn = value; }
        }

        #endregion
    }
}
